/*
 *  Copright: 2008 Philipp Leitner, Distributed Systems Group,
 *            TU Wien, leitner@infosys.tuwien.ac.at
 *
 *  This file is part of DAIOS.
 *
 *  DAIOS is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation.
 * 
 *  DAIOS is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with DAIOS.  If not, see
 *  <http://www.gnu.org/licenses/>.
 * 
 */

package at.ac.tuwien.infosys.dsg.daiosPlugins.axis2.axiom;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;

/**
 * A static untility class containg AXIOM-related helper methods.
 * 
 * @author philipp
 *
 */
public class OMUtil {
	
	/**
	 * Convert a XML document given as String to AXIOM. Parse the
	 * XML doc using StAX and return the root element as OMElement.
	 * 
	 * @param s The XML document as String.
	 * @return The root element.
	 * @throws XMLStreamException
	 */
	public static OMElement getRootNode(String s) throws XMLStreamException {
		
        XMLInputFactory xif = XMLInputFactory.newInstance();
        XMLStreamReader reader =
        	xif.createXMLStreamReader(new ByteArrayInputStream(s.getBytes()));
        StAXOMBuilder builder= new StAXOMBuilder(reader);
        return builder.getDocumentElement();
        
	}
	
	public static OMElement getRootNodeFromIS(InputStream is) throws XMLStreamException {
		
        XMLInputFactory xif = XMLInputFactory.newInstance();
        XMLStreamReader reader =
        	xif.createXMLStreamReader(is);
        StAXOMBuilder builder= new StAXOMBuilder(reader);
        return builder.getDocumentElement();
        
	}	
	
	/**
	 * Add a list of OM elements as children to a parent element.
	 * 
	 * @param parent
	 * @param children
	 */
	public static void addAllChilds(OMElement parent, List<OMElement> children) {
		for(OMElement child : children) {
			parent.addChild(child);
		}
	}
	
	/**
	 * Get the <i>previous</i> OM element sibling of an element.
	 * 
	 * @param el
	 */
	public static OMElement getPreviousOMElement(OMElement el) {
		OMNode o = el;
		while(o.getPreviousOMSibling() != null &&
			  !(o.getPreviousOMSibling() instanceof OMElement))
			o = o.getPreviousOMSibling();
		
		if(o.getPreviousOMSibling() != null)
			return (OMElement) o.getPreviousOMSibling();
		else
			return null;
	}

	/**
	 * Get the <i>next</i> OM element sibling of an element.
	 * 
	 * @param el
	 */	
	public static OMElement getNextOMElement(OMElement el) {
		OMNode o = el;
		while(o.getNextOMSibling() != null &&
			  !(o.getNextOMSibling() instanceof OMElement))
			o = o.getNextOMSibling();
		
		if(o.getNextOMSibling() != null)
			return (OMElement) o.getNextOMSibling();
		else
			return null;
	}
	
	/**
	 * Check if a given OM element has any child <i>elements</i>.
	 * 
	 * @param el
	 */
	public static boolean hasSubelement(OMElement el) {
		
		Iterator children = el.getChildElements();
		return children.hasNext();
		
	}
	
	/**
	 * Get the 'Body' element from a SOAP message in
	 * AXIOM notion.
	 * 
	 * @param result The entire SOAP message.
	 * @return The 'Body' of the SOAP message given.
	 */
	public static OMElement getBody(OMElement result) {
		
		Iterator it = result.getChildren();
		OMElement next = null;
		while(it.hasNext()) {
			next = (OMElement)it.next();
			if(next.getLocalName().equals("Body"))
				return next;
		}
		
		return null;
	}
	
	/**
	 * Get the actual payload from a SOAP body.
	 * 
	 * <p>
	 * 
	 * The payload is simply the first child element
	 * of the body.
	 * 
	 * @param body The SOAP body.
	 * @return The payload of the SOAP message.
	 */
	public static OMElement getPayload(OMElement body) {
		
		Iterator it = body.getChildren();
		
		return (OMElement)it.next();
	}
	
}
